fix: [SDK-4901] skip ShortcutBadger on API 26+ to prevent SIGSEGV on Xiaomi devices - #2570
Conversation
26c7e3a to
905aefb
Compare
📊 Diff Coverage ReportDiff Coverage Report (Changed Lines Only)Gate: aggregate coverage on changed executable lines must be ≥ 80% (JaCoCo line data for lines touched in the diff). Changed Files Coverage
Overall (aggregate gate)5/6 touched executable lines covered (83.3% — requires ≥ 80%) |
905aefb to
5139ef3
Compare
4a6177c to
3c784ce
Compare
On Android 8+ (API 26), notification channels handle app icon badges natively, making ShortcutBadger unnecessary. ShortcutBadger's DefaultBadger fallback causes native SIGSEGV crashes on certain Xiaomi devices (Redmi 10C, Redmi 9A) where MIUI's broadcast receiver has buggy native code that cannot be caught at the Java level. Fixes OneSignal/react-native-onesignal#1766 Made-with: Cursor Co-authored-by: Cursor <cursoragent@cursor.com>
3c784ce to
f251cfd
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
@claude review |
There was a problem hiding this comment.
LGTM — straightforward, well-tested fix.
Extended reasoning...
Overview
This PR changes BadgeCountUpdater.update() and updateCount() to skip ShortcutBadger entirely on API 26+ (Android O and above), guarding against a native SIGSEGV crash observed on some Xiaomi devices. The refactor introduces a private constructor with an injected _sdkInt field (defaulting to Build.VERSION.SDK_INT via a public secondary constructor) plus a @VisibleForTesting factory method, enabling the new unit tests to exercise both old and new SDK-version branches deterministically. Only two files are touched: the production class and its new test file.
Security risks
None. This is a defensive change to skip a legacy compatibility library on newer API levels; it does not touch auth, crypto, network, or data handling.
Level of scrutiny
Low-to-moderate is appropriate here. The change is small, localized to a single class, does not alter the public API surface (the primary constructor is now private but a compatible public secondary constructor preserves external construction), and existing callers construct BadgeCountUpdater through the DI module using the public constructor, which is unaffected. The bug-hunting pass found no issues, and I independently confirmed no other callers rely on the old primary constructor.
Other factors
Test coverage is solid: new unit tests explicitly cover the O-and-above skip path for both update() and updateCount(), and confirm the pre-O and pre-M paths still invoke ShortcutBadger as before. Diff coverage is 80% (4/5 changed executable lines), just meeting the CI gate. The three candidate lint/detekt concerns raised by the finder agents (missing @ChecksSdkIntAtLeast, @RequiresApi lint recognition, detekt baseline) are Kotlin-file style/tooling nitpicks that don't affect runtime correctness and were correctly ruled out.
…Xiaomi devices (#2570) Co-authored-by: Cursor <cursoragent@cursor.com>
Description
One Line Summary
Skip ShortcutBadger badge updates on Android 8+ (API 26) to prevent native SIGSEGV crashes on Xiaomi devices.
Details
Motivation
ShortcutBadger causes a native SIGSEGV on certain Xiaomi devices (Redmi 10C, Redmi 9A) running Android 11-13. The crash occurs while updating the legacy launcher badge. Since SIGSEGV is a native crash, Java exception handling cannot intercept it.
Android 8+ handles app icon badges through notification channels and active notifications, so the legacy ShortcutBadger path is unnecessary on those versions.
Reported in OneSignal/react-native-onesignal#1766 and #2222. Tracked by SDK-4901.
Scope
On API 26+, skip both automatic and explicit ShortcutBadger updates. Pre-API 26 devices continue using ShortcutBadger unchanged.
Testing
Unit testing
Added
BadgeCountUpdaterTestscovering:update()does not invoke ShortcutBadger on API 26.updateCount()does not invoke ShortcutBadger on API 26.updateCount()continues invoking ShortcutBadger before API 26.Local validation:
Manual testing
The affected Xiaomi hardware was not available locally. The regression tests prevent the crashing code path from being reached on the reported Android versions.
Affected code checklist
Checklist
Overview
Testing
Final pass